package com.inspur.edp.cef.core.validation.enumvaladaptor;

import com.inspur.edp.cef.api.exceptions.ErrorCodes;
import com.inspur.edp.cef.api.message.IBizMessage;
import com.inspur.edp.cef.api.message.ISupportBizMessage;
import com.inspur.edp.cef.api.message.MessageLevel;
import com.inspur.edp.cef.api.validation.ICefValidationContext;
import com.inspur.edp.cef.entity.changeset.AbstractModifyChangeDetail;
import com.inspur.edp.cef.entity.changeset.ChangeType;
import com.inspur.edp.cef.entity.changeset.IChangeDetail;
import com.inspur.edp.cef.spi.entity.info.EnumValueInfo;
import com.inspur.edp.cef.spi.validation.IValidation;
import io.iec.edp.caf.commons.exception.CAFRuntimeException;
import io.iec.edp.caf.commons.exception.ExceptionLevel;

import java.util.Arrays;
import java.util.List;

public abstract class EnumValAdaptor<T> implements IValidation {
    protected String propName;
    protected List<EnumValueInfo> enumValueInfos;
    public EnumValAdaptor(String propName, List<EnumValueInfo> enumValueInfos){
        this.propName = propName;
        this.enumValueInfos = enumValueInfos;
    }
    @Override
    public final boolean canExecute(IChangeDetail change) {
        if (change == null) {
            return true;
        }
        AbstractModifyChangeDetail modifyChange = (AbstractModifyChangeDetail)((change instanceof AbstractModifyChangeDetail) ? change : null);
        if (modifyChange != null)
        {
            return modifyChange.getPropertyChanges() != null && modifyChange.getPropertyChanges().containsKey(propName);
        }
        return change.getChangeType() == ChangeType.Added;
    }

    @Override
    public final void execute(ICefValidationContext context, IChangeDetail change)
    {
        try {
            if (context.getData() == null || isValid((T) context.getData().getValue(propName)))
                return;
        }
        catch(Exception e) {
            throw new RuntimeException("字段[" + propName + "]检查长度精度时发生异常", e);
        }
        onInvalid(context);
    }

    private void onInvalid(ICefValidationContext context) {
        if(context instanceof ISupportBizMessage){
            IBizMessage msg = ((ISupportBizMessage) context)
                    .createMessageWithLocation(MessageLevel.Error, Arrays.asList(propName),
                            getDisplayMessage(context));
            ((ISupportBizMessage) context).addMessage(msg);
        }else {
            throw new CAFRuntimeException("", ErrorCodes.Length, getDisplayMessage(context), null,
                    ExceptionLevel.Warning, true);
        }
    }

    protected abstract String getDisplayMessage(ICefValidationContext context);
    protected abstract boolean isValid(T value);
}
